package com.zzw.service.impl;

import com.alibaba.fastjson.JSON;
import com.zzw.dto.AssignAuthDto;
import com.zzw.entity.Auth;
import com.zzw.mapper.AuthMapper;
import com.zzw.service.AuthService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @Project: warehouse
 * @Description:
 * @Author: zzw
 */
@Service
@Slf4j
public class AuthServiceImpl implements AuthService {

    @Autowired
    private AuthMapper authMapper;

    // 注入Redis模板
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public List<Auth> findAuthTree(int userId) {
        // 先从redis中查询缓存，查到的是权限树List<Auth>转的json串
        String authTressListJson = redisTemplate.opsForValue().get(userId + ":authTree");
        // redis中查到缓存
        if (StringUtils.hasText(authTressListJson)) {
            // 将json串转回权限树List<Auth>并返回
            return JSON.parseArray(authTressListJson, Auth.class);
        }
        // redis中没有查询到缓存，从数据库中查询
        List<Auth> allAuthList = authMapper.findAllAuth(userId);
        // 将所有权限List<Auth>转成权限树List<Auth>
        List<Auth> authTreeList = allAuthToAuthTree(allAuthList, 0);
        // 将权限树List<Auth>转成json串并保存到redis
        redisTemplate.opsForValue().set(userId + ":authTree", JSON.toJSONString(authTreeList));
        // 返回权限树
        return authTreeList;
    }

    // 将所有权限转成权限树的递归算法
    private List<Auth> allAuthToAuthTree(List<Auth> allAuthList, int parentId) {
        // 获取父权限id为参数parentId的所有权限
        List<Auth> authList = new ArrayList<Auth>();
        for (Auth auth : allAuthList) {
            if (auth.getParentId() == parentId) {
                authList.add(auth);
            }
        }
        // 查询List<Auth> authList中每个权限的所有子级权限
        for (Auth auth : authList) {
            List<Auth> childAuthList = allAuthToAuthTree(allAuthList, auth.getAuthId());
            auth.setChildAuth(childAuthList);
        }
        return authList;
    }

    @Override
    public List<Auth> allAuthTree() {
        // 先从redis缓存中查询缓存，查到的是整个权限树List<Auth>转的json串
        String allAuthTreeJson = redisTemplate.opsForValue().get("all:authTree");
        // redis中查到缓存
        if (StringUtils.hasText(allAuthTreeJson)) {
            // 将json串转回权限树List<Auth>并返回
            return JSON.parseArray(allAuthTreeJson, Auth.class);
        }
        // redis中没有查到缓存，从数据库表中查询
        List<Auth> allAuthList = authMapper.getAllAuth();
        // 将所有权限转成权限树
        List<Auth> allAuthTreeList = allAuthToAuthTree(allAuthList, 0);
        // 将整个权限树List<Auth>转成json串并保存到redis
        redisTemplate.opsForValue().set("all:authTree", JSON.toJSONString(allAuthTreeList));
        // 返回整个权限树
        return allAuthList;
    }

    @Transactional
    @Override
    public void assignAuth(AssignAuthDto assignAuthDto) {

        // 拿到角色id
        Integer roleId = assignAuthDto.getRoleId();
        // 拿到给角色分配的所有权限(菜单)id
        List<Integer> authIds = assignAuthDto.getAuthIds();
        // 根据角色id删除给角色已分配的所有权限
        authMapper.deleteAllAuth(roleId);
        // 循环添加角色权限关系
        for (Integer authId : authIds) {
            authMapper.insertRoleAuth(roleId, authId);
        }
    }
}
